<template>
    <div class="goods">
      <!--左侧菜单列表 -->
      <div class="menu-wrapper" ref="menuWrapper">
        <ul>
          <li v-for="(item,index) in goods" class="menu-item" :class="{'current' : currentIndex === index}" :key="index"
           @click="selectMenu(index,$event)" ref="menuList">
            <span class="text border-1px" >
              <span class="icno" :class="classMap[goods[index].type]"></span>{{item.name}}
            </span>
          </li>
        </ul>
      </div>
      <!--右侧商品列表 -->
      <div class="foods-wrapper" ref="foodsWrapper">
        <ul>
          <li v-for="(item,index) in goods" :key="index" class="food-list" ref="foodList">
            <!--菜单名称 -->
            <h1 class="title">{{item.name}}</h1>
            <!--该菜单下所有商品 -->
            <ul>
              <li v-for="(food,index) in item.foods" :key="index" class="food-item border-1px" @click="clickFood(food,$event)">
                <div class="icno">
                  <!--图片设定宽高 -->
                  <!-- <img :src="food.image" width="70" height="70"/> -->
                  <!--使用loadying -->
                  <img v-lazy = "food.image" width="70" height="70" />
                </div>
                <div class="content">
                  <h2 class="name">{{food.name}}</h2>
                  <p class="desc">{{food.description}}</p>
                  <div class="extra">
                    <!--若将span与span换行,则它们之间存在较大间隙 -->
                    <span class="count">月售{{food.sellCount}}份</span><span>好评率{{food.rating}}%</span>
                  </div>
                  <div class="price">
                    <!--若将span与span换行,则它们之间存在较大间隙 -->
                    <span class="now">￥{{food.price}}</span><span class="old" v-show="food.oldPrice">￥{{food.oldPrice}}</span>
                  </div>
                  <!--添加购物车数量组件 绝对定位 cartcontrol子组件中通过$.emit('addCart',addFood)传递到goods父组件addFood() 展示抛物小球 -->
                  <div class="cartcontrol-wrapper">
                    <cartcontrol :food="food" @addCart="addFood"></cartcontrol>
                  </div>
                </div>
              </li>
            </ul>
          </li>
        </ul>
      </div>
      <!--底部购物车组件 通过ref="food"绑定子组件shopcart并调用drop()  selectFoods将shopcart组件与cartcontrol组件进行关联-->
      <!--shopcart子组件中通过$.emit('addCart',addFood)传递到goods父组件addFood() 展示抛物小球 -->
      <shopcart ref="shopcart"  @addCart="addFood" :select-foods="selectFoods" :delivery-price="seller.deliveryPrice" :min-price="seller.minPrice"></shopcart>
      <!--商品详情组件 :传递子组件采用驼峰式命名方式 通过ref="food"绑定子组件food并调用show()-->
      <food :food = "clickedFood" @addCart="addFood"  ref="food"></food>
      <!--food子组件中通过$.emit('addCart',addFood)传递到goods父组件addFood() 展示抛物小球 -->
     
      <div class="loading-container">
         <!--loading加载 -->
        <loading v-show="!goods.length"></loading>
      </div>
    </div>
</template>
<script>
import BScroll from 'better-scroll';
import $http from '../../utils/http.js';
import api from '../../api/app.js';
import shopcart from '../shopcart/shopcart.vue';
import cartcontrol from '../base/cartcontrol/cartcontrol.vue';
import food from '../food/food.vue';
import loading from '../base/loading/loading.vue';

export default {
  props:{
    seller: {
      type: Object
    }
  },
  components:{
    shopcart,
    cartcontrol,
    food,
    loading
  },
  data() {
    return {
      goods:[],
      listHeight:[],
      scrollY:0,
      clickedFood:{}//商品详情
    };
  },
  computed:{
    currentIndex() {    // 只有当 currentIndex === index 为true，应用的class才生效
      console.log('计算属性computed中的currentIndex()方法');
      console.log(this.listHeight);
      for(let i = 0; i< this.listHeight.length;i++){
        let height1 = this.listHeight[i];
        let height2 = this.listHeight[i + 1];
        console.log('scrollY 初始化 ' + this.scrollY +'   ' +height1 +'  '+ height2);
        if( !height2 || (this.scrollY >= height1 && this.scrollY < height2)) { //若height1为最后一个值，则height2不存在,即添加!height2判断
          this._followScroll(i);
          return i ;
        }    
        // return 0 ;//没有滚动效果的错误写法
      }
      return 0;
    },
    // 1.变量所有商品 将cartcontrol组件与shopcart组件进行关联
    selectFoods() {
      let foods = [];
      this.goods.forEach((good) =>{
        good.foods.forEach((food) => { //切记不可写成 this.good.foods，this指向有问题
           if(food.count){
             foods.push(food);
           }
        })
      });
      return foods;
    }
  },
  created() {
    this.goodsInfo();// 初始化商品信息
    this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee'];
    
  },
  methods: {
    goodsInfo: async function() {
      console.log('goods.length   ' + this.goods.length);
      const res = await $http.post(api.goods);
      //模拟测试数据
      setTimeout(() => {
        this.goods = res.data;
        console.log(res);
        this.$nextTick(() => { //确保dom元素渲染更新完毕,dom元素发生变化发生在nextTick回调函数之后,因此有关dom的操作需要此回调函数
        //初始化better-scroll 替换成 setTimeout(fn, 20) 也是可以的（20 ms 是一个经验值，每一个 Tick 约为 17 ms），对用户体验而言都是无感知的
        this._initScroll();
        this._calculateHeight();
       });
      }, 0);
    },
    //设置滚动,
    _initScroll() {
      console.log('通过this.$refs属性获取ref属性绑定的dom元素' + this.$refs.menuWrapper );
      this.meunScroll = new BScroll(this.$refs.menuWrapper,{
        click: true  // 开启点击事件（BS默认会阻止掉）
      });
      
      this.foodScroll = new BScroll(this.$refs.foodsWrapper,{
        click:true, //开启点击事件 cartcontrol组件中触发addCart()
        probeType: 3 // 设定BS 实时监测滚动位置
      });
      
      //监听scroll事件
      this.foodScroll.on('scroll', (position) => {
        // 判断滑动方向，避免下拉时分类高亮错误（如第一分类商品数量为1时，下拉使得第二分类高亮）
        //console.log('position.y ' + position.y);
        console.log('Math.floor ' + Math.round(position.y)); //取值
        this.scrollY = Math.abs(Math.round(position.y)) // Math.abs()绝对值
      });

    },
    /**
     * 1.获取li对应的class样式的区间高度，且存放到listHeight中(即递增的区间数组,标识每个区间对应的高度)
     * 2.定义scrollY，跟踪右侧scrolly的值
     *    使用监听事件scroll，获取position.y的高度
     * 3.scrollY的值与listHeight的索引值进行映射
     *    通过计算属性computed设置 currentIndex()方法，scrollY在listHeight[i] 与 listHeight[i+1]区间中，返回当前索引i
     * 4.通过currentIndex的索引设置对应的样式
     *    :class="{'current' : currentIndex === index}"
     */
    _calculateHeight(){
      let foodList = this.$refs.foodList;// 每个foodlist的高度就是每个区块的高度
      //console.log(foodList);
      let height = 0;//递增高度
      this.listHeight.push(height);
      for (let i = 0 ; i < foodList.length ; i++){
        height += foodList[i].clientHeight; // clientHeight 每个区块的可视高度
        //console.log(' height '+height);
        this.listHeight.push(height);
      }
    },
    //点击菜单显示对应的区域
    selectMenu(index,event){
      console.log('触发index区域selectMenu()方法  ' + index + '事件event的值 ' + event); // 触发index区域selectMenu()方法  2事件event的值 [object MouseEvent]
      console.log(event);
      if(!event._constructed){ //兼容pc端触发2次事件
        return;
      }
      //对应的节点scrollToElement()事件
      let foodList = this.$refs.foodList;
      let el = foodList[index]; 
      this.foodScroll.scrollToElement(el,300); //BS接口，滚动至当前对应的索引区域
    },
    //cartcontrol子组件传递到父组件goods, // 监听子元素的add事件，执行addFodd函数
    addFood(target) {
      console.log('将cartcontrol子组件中的dom传递到goods父组件里');
      console.log(target);
      //使用$refs获取组件shopcart或者div模块元素，即ref=shopcart或者ref=menuWrapper进行相应的绑定
      this.$nextTick(()=>{ //添加回调函数的作用为了实现小球抛出的体验效果优化，异步执行下落动画
        this.$refs.shopcart.drop(target); // 父组件goods访问子组件shopcart的方式，调用子组件的方法，传值
      })
    },
    //商品详情
    clickFood(food,event){
      //兼容pc
       if(!event._constructed){ //兼容pc端触发2次事件
        return;
      }
      console.log('触发clickFood事件  ');
      this.clickedFood = food;
      this.$refs.food.show();//父组件goods访问子组件food中的show()方法，调用子组件的方法
    }, 
    
    _followScroll(index) {
      let menuList = this.$refs.menuList;
      let el = menuList[index];
      this.meunScroll.scrollToElement(el, 300);
    }
  }
};
</script>
<style lang="scss" rel="stylesheet/scss">
@import "../../assets/style/mixin.scss";

.goods {
  display: flex; //flex布局
  position: absolute;
  overflow: hidden;//超过部分隐藏
  top: 174px;
  bottom: 46px;//预留购物车展示
  width: 100%;
  .menu-wrapper {
    flex: 0 0 80px; //占位空间
    width: 80px;
    background: #f3f5f7;
    .menu-item {
      display: table;//垂直居中且能自动换行,使用table布局
      line-height: 14px;
      padding: 0 12px;
      text-align: center;
      width: 56px;
      height: 54px;
      font-size: 12px;  
      &.current {
      position: relative;
        z-index: 10;
        margin-top: -1px;
        background: #fff;
        .text {
          @include border-none();
          color: #000;
          font-weight: 500;
        } 
      }
      .text {
        display: table-cell;//父元素使用display:table
        width: 56px;
        vertical-align: middle;/*在table中居中*/
        // border-bottom: 1px solid rgba(7,17,27, 0.1);
        @include border-1px(rgba(7, 17, 27, 0.1));
        font-size: 12px;
        color: rgb(78, 78, 78);
        .icno {
          vertical-align: top;
          display: inline-block;
          width: 12px;
          height: 12px;
          margin-right: 4px;
          background-size: 12px 12px;
          background-repeat: no-repeat;
          &.decrease {
            @include bg-img('decrease_3')
          }
          &.discount {
            @include bg-img('discount_3')
          }
          &.guarantee {
            @include bg-img('guarantee_3')
          }
          &.invoice {
            @include bg-img('invoice_3')
          }
          &.special {
            @include bg-img('special_3')
          }
        }
      }  
    }
  }
  .foods-wrapper {
    flex: 1;
    .food-list {
      .title {
        padding-left: 14px;
        height: 26px;
        line-height: 26px;
        border-left: 2px solid #d9dde1;
        background: #f3f5f7;
        font-size: 12px;
        color: rgb(147, 153, 159);
      }
      .food-item {
        display: flex; // flex布局
        margin: 18px;//顶部与左侧
        padding-bottom: 18px; //margin与padding-bottom重叠
        @include border-1px(rgba(7, 17, 27, 0.1)); //设置1像素
        &:last-child{
           @include border-none();//取消1像素
           margin-bottom: 0px;
        }
        .icno {
          flex: 0 0 70px;//占位空间
          margin-right: 10px;
          img {
              border-radius: 2px;
          }
        }
        .content {
          flex: 1;
          .name {
            margin: 2px 0 8px 0;
            font-size: 14px;
            height: 14px;
            line-height: 14px;
            color:rgb(7, 17, 27);
            width: 136px;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }
          .desc {
            margin-bottom: 8px;
            line-height: 14px;
            font-size: 10px;
            color: rgb(147, 153, 159);
            overflow: hidden;
            -webkit-line-clamp: 2;
            word-break: break-all;
            display: -webkit-box;
            -webkit-box-orient: vertical;
          }
          .extra {
            line-height: 10px;
            font-size: 10px;
            color: rgb(147, 153, 159);
            .count {
              margin-right: 12px;
            }
          }
          .price {
             line-height: 24px;
             font-weight: 700;
             font-size: 0;
             .now {
                margin-right: 8px;
                font-size: 14px;
                font-weight: 900;
                color: #fa3a12;
              }
              .old {
                text-decoration: line-through;
                font-size: 10px;
                color: rgb(147, 153, 159);
              }
          }
          .cartcontrol-wrapper {
            position: absolute;
            bottom: 5px;
            right: 0;
          }
        }
      }
    }
  }
  .loading-container {
    position: absolute;
    width: 100%;
    top: 50%;
    transform: translateY(-50%);
  }
}
</style>


